package edu.hawaii.duedates.lender;

import java.util.ArrayList;
import java.util.List;
import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.HttpUnitOptions;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;
import edu.hawaii.duedates.ItemDue;

/**
 * A class for the UH Manoa Library system that implements LibraryVault. 
 * Stores information about URL and login form data. Implements methods 
 * for logging in and returning data from the library.
 * 
 * @author Tyler Wolff and Scheller Sanchez
 */
public class UhManoaLibrary implements Lender {
  private static final String name = "UH Manoa Library";
  
  // Url for the login page of the UH Manoa Library system
  private static final String libUrl = "http://uhmanoa.lib.hawaii.edu/cgi-bin/Pwebrecon."
    + "cgi?DB=local&PAGE=pbLogon";
  
  // Form information for the Uh Library System
  private static final String formName = "logonpage";
  private static final String param1 = "BC";
  private static final String param2 = "LN";
  
  /**
   * Attempts to login to a given Library system with user information. System makes use of an
   * HttpUnit WebConversation to scan a systems web page for login form, then inputs user
   * information and submits. If login was unsuccessful, returns null WebConversation.
   * 
   * @param id The user ID or first login parameter.
   * @param pass The user password or second login parameter.
   * @return The WebConversation instance after successful login.
   * @throws Exception If error occurs scrapping web page.
   */
  public WebConversation login (String id, String pass) throws Exception {

    // If website has bogus JavaScript code, do not throw error.
    HttpUnitOptions.setExceptionsThrownOnScriptError(false);
    // create the conversation object which will maintain state for us
    WebConversation conversation = new WebConversation();
    WebRequest request = new GetMethodWebRequest(UhManoaLibrary.getLibUrl());
    WebResponse response = conversation.getResponse(request);
    
    WebForm form = response.getFormWithName(UhManoaLibrary.getFormName());
    form.setParameter(UhManoaLibrary.getParam1(), id);
    form.setParameter(UhManoaLibrary.getParam2(), pass);
    form.submit();
    response = conversation.getCurrentPage();
      
    // Return null conversation if Login unsuccessful
    if (response.getText().contains("Sorry, Login unsuccessful")) {
      conversation = null;
      System.out.println("-- Login to the UH Manoa Library was unsuccessful --");
    }
    
    return conversation;

  } // end login
  
  /**
   * Given valid login information for the UH Library site, provides info 
   * about a user's borrowed library books. Returns empty itemsDue list if
   * there are no books out.
   * 
   * @param id The UH user ID.
   * @param lastName The UH user's last name.
   * @return A List of ItemDue objects.
   * @throws Exception if login was unsuccessful.
   */
  public List<ItemDue> getItemInfo (String id, String lastName)
      throws Exception {

      List<ItemDue> itemsDue = new ArrayList<ItemDue>();
      
    try { 
      
      WebConversation conversation = this.login(id, lastName);
      
      // If login was unsuccessful
      if (conversation == null) {
        return itemsDue;
      }
      
      WebResponse response = conversation.getCurrentPage();
      WebTable tableOut = null;
      WebTable[] tables = response.getTables();
   
      // Looks for the table with checked out books.
      for (WebTable table : tables) {
        if (table.getText().contains("Item Type") && table.getText().contains("Status")) {
          tableOut = table;
        }
      }
      
      // whiteSpace created to account for all sized book descriptions
      String whiteSpace = "                                                  ";                

      if (tableOut != null) {
        // Checks for table with renew option (No patron blocks)
        if (tableOut.getText().contains("Renew?")) {
          for (int i = 1; i < tableOut.getRowCount(); i++) {
            String DueDate = tableOut.getCellAsText(i, 3);
            DueDate = DueDate.substring((DueDate.indexOf(':') + 6));
            ItemDue tempItem = new ItemDue("UH Manoa", 
                tableOut.getCellAsText(i, 1).concat(whiteSpace), tableOut
                .getCellAsText(i, 2), DueDate);
            itemsDue.add(tempItem);
          }
        }
        // Checks for table without renew option (With patron blocks)
        else {
          for (int i = 1; i < tableOut.getRowCount(); i++) {
            String DueDate = tableOut.getCellAsText(i, 2);
            DueDate = DueDate.substring((DueDate.indexOf(':') + 6));
            ItemDue tempItem = new ItemDue("UH Manoa", 
                tableOut.getCellAsText(i, 0).concat(whiteSpace), tableOut
                .getCellAsText(i, 1), DueDate);
            itemsDue.add(tempItem);
          }
        }

      } // end if

      return itemsDue;

    } // end try
    catch (Exception e) {
      throw new Exception(e.getMessage(), e);
    } 
    
  } // end getItemInfo class
  
  /**
   * Returns the url of Library.
   * 
   * @return The url of the Library.
   */
  private static String getLibUrl() {
    return libUrl;
  }

  /**
   * Returns the login form name of Library.
   * 
   * @return The Name of login form.
   */
  private static String getFormName() {
    return formName;
  }

  /**
   * Returns the name of the first input parameter
   * in login form.
   * 
   * @return The Name of parameter 1.
   */
  private static String getParam1() {
    return param1;
  }

  /**
   * Returns the name of the second input parameter
   * in login form.
   * 
   * @return The Name of parameter 2.
   */
  private static String getParam2() {
    return param2;
  }
  
  /**
   * Gets library name.
   * 
   * @return Library name.
   */
  public String getLenderName() {
    return name;
  }

} // end of UhManoaLibrary class